using Unity.Assertions;
using Unity.Burst;
using Unity.Burst.Intrinsics;
using Unity.Collections;
using Unity.Entities;
using Unity.Transforms;

namespace HelloCube.JobChunk
{
    public partial struct RotationSystem : ISystem
    {
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            state.RequireForUpdate<Execute.IJobChunk>();
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            var cubesQuery = SystemAPI.QueryBuilder().WithAll<RotateSpeed, LocalTransform>().Build();

            RotationJob job = new RotationJob()
            {
                TransformTypeHandle = SystemAPI.GetComponentTypeHandle<LocalTransform>(),
                RotateSpeedTypeHandle = SystemAPI.GetComponentTypeHandle<RotateSpeed>(),
                DeltaTime = SystemAPI.Time.DeltaTime,
            };

            state.Dependency = job.Schedule(cubesQuery, state.Dependency);
        }
    }

    [BurstCompile]
    struct RotationJob : IJobChunk
    {
        public ComponentTypeHandle<LocalTransform> TransformTypeHandle;
        [ReadOnly] public ComponentTypeHandle<RotateSpeed> RotateSpeedTypeHandle;
        public float DeltaTime;

        public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask,
            in v128 chunkEnabledMask)
        {
            Assert.IsFalse(useEnabledMask); //useEnabledMask 默认为 false
            var transforms = chunk.GetNativeArray(ref TransformTypeHandle);
            var rotateSpeeds = chunk.GetNativeArray(ref RotateSpeedTypeHandle);
            for (int i = 0, chunkEntityCount = chunk.Count; i < chunkEntityCount; i++)
            {
                transforms[i] = transforms[i].RotateY(rotateSpeeds[i].RadiansPerSecond * DeltaTime);
            }
        }
    }
}